unit uSBD_BaseTypes;
interface
uses
  Classes, SysUtils, uSBD_ServiceProvider;

type
TSBDUnit_Exception = class( Exception)
  private
    FRaisingClass: TClass;
  public
    constructor Create( RaisingClass1: TClass; const Msg: string);
    constructor CreateFmt( RaisingClass1: TClass; const Msg: string; const Args: array of const);
    property RaisingClass: TClass  read FRaisingClass;
  end;
TSBDUnit_ExceptionClass = class of TSBDUnit_Exception;

const
  ECode_Query: cardinal = cardinal( -1);
  ECode_NA   : cardinal = cardinal( -2);

type
TSBDUnit_WinAPIException = class( TSBDUnit_Exception)
  public
  public
    FErrCode: cardinal;
    constructor Create( const Msg: string = ''; ErrCode: cardinal = cardinal( -1));

  protected
    function    StockMessage: string; virtual;
    function    MsgPrefix: string; virtual;
  end;

TSBD_RefCountedCommonBase = class abstract( TInterfacedObject)
  protected
    [Injection] FServiceProvider: IServiceProvider;
    class procedure RaiseException( const Msg: string);                                virtual;
    class procedure RaiseExceptionFmt( const Msg: string; const Args: array of const); virtual;
    class function  ExceptionClass: TSBDUnit_ExceptionClass;                           virtual;
    function AcquireService( const IID: TGUID; out Intf; const Config: string = ''): boolean;
    procedure SetParentNodeAsIntf( const Value: IInterface);    virtual;

  public
    class procedure RegisterThis( const Registrar: IServiceProvider; const IID: TGUID);

    [Injection('client')]
    property ParentNodeAsIInterface: IInterface write SetParentNodeAsIntf;
  end;


TSBD_NonCountedCommonBase = class abstract( TInterfacedPersistent)
  protected
    [Injection] FServiceProvider: IServiceProvider;
    class procedure RaiseException( const Msg: string);                                virtual;
    class procedure RaiseExceptionFmt( const Msg: string; const Args: array of const); virtual;
    class function  ExceptionClass: TSBDUnit_ExceptionClass;                           virtual;
    function AcquireService( const IID: TGUID; out Intf; const Config: string = ''): boolean;
    procedure SetParentNodeAsIntf( const Value: IInterface);    virtual;

  public
    [Injection('client')]
    property ParentNodeAsIInterface: IInterface write SetParentNodeAsIntf;
   end;



implementation




uses Windows;
{ TSBDUnit_Exception }

constructor TSBDUnit_Exception.Create( RaisingClass1: TClass; const Msg: string);
begin
FRaisingClass := RaisingClass1;
inherited Create( Msg)
end;

constructor TSBDUnit_Exception.CreateFmt( RaisingClass1: TClass;
  const Msg: string; const Args: array of const);
begin
FRaisingClass := RaisingClass1;
inherited CreateFmt( Msg, Args)
end;

{ TSBD_RefCountedCommonBase }

function TSBD_RefCountedCommonBase.AcquireService(
  const IID: TGUID; out Intf; const Config: string): boolean;
begin
result := assigned( FServiceProvider) and
          FServiceProvider.Acquire( self as IInterface, IID, Intf, Config)
end;

class function TSBD_RefCountedCommonBase.ExceptionClass: TSBDUnit_ExceptionClass;
begin
result := TSBDUnit_Exception
end;


class procedure TSBD_RefCountedCommonBase.RaiseException( const Msg: string);
begin
raise ExceptionClass.Create( self, Msg)
end;

class procedure TSBD_RefCountedCommonBase.RaiseExceptionFmt(
  const Msg: string; const Args: array of const);
begin
raise ExceptionClass.CreateFmt( self, Msg, Args)
end;

class procedure TSBD_RefCountedCommonBase.RegisterThis(
  const Registrar: IServiceProvider; const IID: TGUID);
begin
  if assigned( Registrar) then
    Registrar.RegisterServiceClass( self, IID).Free
end;


procedure TSBD_RefCountedCommonBase.SetParentNodeAsIntf(
  const Value: IInterface);
begin
end;

{ TSBD_NonCountedCommonBase }

function TSBD_NonCountedCommonBase.AcquireService(
  const IID: TGUID; out Intf; const Config: string): boolean;
begin
result := assigned( FServiceProvider) and
          FServiceProvider.Acquire( self as IInterface, IID, Intf, Config)
end;

class function TSBD_NonCountedCommonBase.ExceptionClass: TSBDUnit_ExceptionClass;
begin
result := TSBDUnit_Exception
end;


class procedure TSBD_NonCountedCommonBase.RaiseException( const Msg: string);
begin
raise ExceptionClass.Create( self, Msg)
end;

class procedure TSBD_NonCountedCommonBase.RaiseExceptionFmt(
  const Msg: string; const Args: array of const);
begin
raise ExceptionClass.CreateFmt( self, Msg, Args)
end;

procedure TSBD_NonCountedCommonBase.SetParentNodeAsIntf(
  const Value: IInterface);
begin
end;

{ TSBDUnit_WinAPIException }

constructor TSBDUnit_WinAPIException.Create( const Msg: string; ErrCode: cardinal);
var
  Msg1: string;
begin
  if ErrCode = ECode_Query then
      FErrCode := GetLastError
    else
      FErrCode := ErrCode;
  Msg1 := Msg1;
  if Msg1 = '' then
    begin
    if FErrCode = ECode_NA then
        Msg1 := StockMessage
      else
        Msg1 := SysErrorMessage( FErrCode)
    end;
  Msg1 := MsgPrefix + Msg1;
  if (FErrCode <> ECode_NA) and (Pos('%d',Msg1) > 0) then
      inherited CreateFmt( nil, Msg1, [FErrCode])
    else
      inherited Create( nil, Msg1)
end;

function TSBDUnit_WinAPIException.MsgPrefix: string;
begin
result := ''
end;

function TSBDUnit_WinAPIException.StockMessage: string;
begin
result := 'WinAPI error %d'
end;

end.
